#include "MDL_Uart_Ringbuffer.h"
#include <string.h>
#include <stddef.h>
// #include "semphr.h"  // FreeRTOS信号量头文件

/**
 * @brief 初始化环形缓冲区
 * @param rb 环形缓冲区结构体指针
 * @param buffer 用于存储数据的缓冲区
 * @param size 缓冲区大小，建议为2的幂次方
 * @return None
 */
void uart_ringbuffer_init(uart_ringbuffer_t *rb, uint8_t *buffer, uint16_t size) {
    // 安全检查: 确保参数有效
    if ((rb == NULL) || (buffer == NULL)|| (size <= 0)) {
        return;
    }
    
    rb->buffer = buffer;
    rb->size = size;
    rb->head = 0;
    rb->tail = 0;
    rb->count = 0;
    rb->overflow_count = 0;
    rb->is_dma_mode = false;
}

/**
 * @brief 安全写入数据到环形缓冲区
 * @param rb 环形缓冲区结构体指针
 * @param data 要写入的数据指针
 * @param len 要写入的数据长度
 * @return 实际写入的数据长度
 */
uint16_t uart_ringbuffer_write(uart_ringbuffer_t *rb, const uint8_t *data, uint16_t len) {
    uint16_t u16WriteLen = len;
    uint16_t u16Part1;

    // 安全检查: 确保参数有效
    if ((rb == NULL) || (data == NULL)) {
        return 0;
    }

    // 确保缓冲区大小是2的幂且有效
    if ((rb->size == 0) || ((rb->size & (rb->size - 1)) != 0)) {
        return 0;
    }

    // 修复可能损坏的状态
    if (rb->count > rb->size) {
        rb->count = rb->size;
    }

    // 检查缓冲区是否已满
    if (rb->count >= rb->size) {
        rb->overflow_count += len;
        return 0;
    }

    // 计算可写入的数据量
    uint16_t available_space = rb->size - rb->count;
    if (len > available_space) {
        rb->overflow_count += (len - available_space);
        u16WriteLen = available_space;
    }
    
    // 分段写入
    u16Part1 = (rb->size - rb->head) < u16WriteLen ? (rb->size - rb->head) : u16WriteLen;
    memcpy(&rb->buffer[rb->head], data, u16Part1);
    
    if (u16WriteLen > u16Part1) {
        uint16_t u16Part2 = u16WriteLen - u16Part1; // 声明在使用前
        memcpy(rb->buffer, &data[u16Part1], u16Part2);
    }
    
    // 更新头指针和数据计数
    rb->head = (rb->head + u16WriteLen) & (rb->size - 1);
    rb->count += u16WriteLen;
    
    return u16WriteLen;
}

/**
 * @brief 从环形缓冲区安全读取数据
 * @param rb 环形缓冲区结构体指针
 * @param data 用于存储读取数据的缓冲区
 * @param len 要读取的数据长度
 * @return 实际读取的数据长度
 */
uint16_t uart_ringbuffer_read(uart_ringbuffer_t *rb, uint8_t *data, uint16_t len) {
    uint16_t u16Available;
    uint16_t u16Part1;
    uint16_t u16Part2;
    uint16_t u16ReadLen = len;
    
    // 安全检查: 确保参数有效
    if ((rb == NULL) || (data == NULL)) {
        return 0;
    }
    
    // 检查是否有数据可读
    if (rb->count == 0) {
        return 0;
    }
    
    u16Available = rb->count;
    if (len > u16Available) {
        u16ReadLen = u16Available;
    }
    
    // 分段读取
    u16Part1 = (rb->size - rb->tail) < u16ReadLen ? (rb->size - rb->tail) : u16ReadLen;
    memcpy(data, &rb->buffer[rb->tail], u16Part1);
    
    if (u16ReadLen > u16Part1) {
        u16Part2 = u16ReadLen - u16Part1;
        memcpy(&data[u16Part1], rb->buffer, u16Part2);
    }
    
    // 更新指针
    rb->tail = (rb->tail + u16ReadLen) & (rb->size-1);
    rb->count -= u16ReadLen;
    
    return u16ReadLen;
}

/**
 * @brief 检查环形缓冲区中可用数据量
 * @param rb 环形缓冲区结构体指针
 * @return 缓冲区中可用的数据量
 */
uint16_t uart_ringbuffer_available(const uart_ringbuffer_t *rb) {
    // 安全检查: 确保参数有效
    if (rb == NULL) {
        return 0;
    }
    return rb->count;
}

/**
 * @brief 检查环形缓冲区是否为空
 * @param rb 环形缓冲区结构体指针
 * @return true表示缓冲区为空，false表示缓冲区不为空
 */
bool uart_ringbuffer_is_empty(const uart_ringbuffer_t *rb) {
    // 安全检查: 确保参数有效
    if (rb == NULL) {
        return true; // 空指针视为"空"
    }
    return (rb->count == 0);
}

/**
 * @brief 检查环形缓冲区是否已满
 * @param rb 环形缓冲区结构体指针
 * @return true表示缓冲区已满，false表示缓冲区未满
 */
bool uart_ringbuffer_is_full(const uart_ringbuffer_t *rb) {
    // 安全检查: 确保参数有效
    if (rb == NULL) {
        return false; // 空指针视为"未满"
    }
    return (rb->count == rb->size);
}

/**
 * @brief 重置环形缓冲区
 * @param rb 环形缓冲区结构体指针
 * @return None
 */
void uart_ringbuffer_reset(uart_ringbuffer_t *rb) {
    // 安全检查: 确保参数有效
    if (rb == NULL) {
        return;
    }
    rb->head = 0;
    rb->tail = 0;
    rb->count = 0;
    rb->overflow_count = 0;
}

/**
 * @brief 获取环形缓冲区的溢出计数
 * @param rb 环形缓冲区结构体指针
 * @return 缓冲区溢出次数
 */
uint16_t uart_ringbuffer_get_overflow_count(const uart_ringbuffer_t *rb) {
    // 安全检查: 确保参数有效
    if (rb == NULL) {
        return 0;
    }
    return rb->overflow_count;
}